package algorithm;

import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Field;
import it.unisa.dia.gas.jpbc.Pairing;
import util.TaiHashUtil;
import java.nio.charset.StandardCharsets;

public class CPABEKeyGen {
    private Element g;
    private Pairing pairing;

    public CPABEKeyGen(Element g,Pairing pairing){
        this.g=g;
        this.pairing=pairing;
    }

    /**
     * 生成属性密钥
     * @param attribute  属性列表，属性之间用“，”隔开
     * @param mk 初始化生成的主密钥
     * @return 属性密钥类
     */

    public CPABEAttKey generateAttributeKey(String attribute,CPABEMK mk){
        //分解字符串
        String[] attList = attribute.split(",");
        //生成私钥组件数组
        EAUnion[] Dj=new EAUnion[attList.length];
        EAUnion[] Dj2=new EAUnion[attList.length];
        //计算D
        Field zn=pairing.getZr();
        Element r = zn.newRandomElement().getImmutable();
        //生成D
        Element part1=mk.getAlpha().getImmutable();
        Element part2=g.powZn(r).getImmutable();
        Element reverseBeta=zn.newOneElement().getImmutable().div(mk.getBeta());
        Element D=part1.mul(part2).powZn(reverseBeta).getImmutable();
        for (int i = 0; i < attList.length; i++) {
            Element ri=zn.newRandomElement().getImmutable();
            byte[] bHash=TaiHashUtil.getMD5Str(attList[i]).getBytes(StandardCharsets.UTF_8);
            Element hValue=pairing.getG1().newElementFromHash(bHash,0,bHash.length);
            Element hashPow=hValue.duplicate().powZn(ri);

            Dj[i]=new EAUnion();
            Dj[i].seteData(g.powZn(r).mul(hashPow.duplicate()).getImmutable());
            Dj[i].setAttribute(attList[i]);

            Dj2[i]=new EAUnion();
            Dj2[i].seteData(g.powZn(ri).getImmutable());
            Dj2[i].setAttribute(attList[i]);
        }
        return new CPABEAttKey(D,Dj,Dj2,attList);
    }
}
